package cn.tedu.autoshow.website.service.impl;

import static cn.tedu.autoshow.commons.constants.StatusConstants.*;
import cn.tedu.autoshow.commons.ex.ServiceException;
import cn.tedu.autoshow.commons.pojo.vo.PageData;
import cn.tedu.autoshow.commons.util.OrderNumberGenerator;
import cn.tedu.autoshow.commons.util.PageInfoToPageDataConverter;
import cn.tedu.autoshow.commons.web.ServiceCode;
import cn.tedu.autoshow.website.mapper.TicketListMapper;
import cn.tedu.autoshow.website.mapper.TicketOrderMapper;
import cn.tedu.autoshow.website.pojo.entity.TicketList;
import cn.tedu.autoshow.website.pojo.entity.TicketOrder;
import cn.tedu.autoshow.website.pojo.param.TicketOrderAddNewParam;
import cn.tedu.autoshow.website.pojo.param.TicketOrderUpdaeInfoParam;
import cn.tedu.autoshow.website.pojo.vo.TicketListListItemVO;
import cn.tedu.autoshow.website.pojo.vo.TicketOrderListItemVO;
import cn.tedu.autoshow.website.pojo.vo.TicketOrderStandardVO;
import cn.tedu.autoshow.website.service.ITicketOrderService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Service
@Slf4j
public class TicketOrderServiceImpl implements ITicketOrderService {

    @Autowired
    TicketOrderMapper mapper;
    @Autowired
    TicketListMapper ticketListMapper;

    @Override
    public void addNew(TicketOrderAddNewParam ticketOrderAddNewParam) {
        log.info("【开始】:【新增—购票订单】");
        log.debug("传入参数, cvsTicketOrderAddNewParam={}", ticketOrderAddNewParam);
        LocalDateTime now = LocalDateTime.now();

        TicketOrder ticketOrder =new TicketOrder();
        BeanUtils.copyProperties(ticketOrderAddNewParam, ticketOrder);
        ticketOrder.setOrderNo(OrderNumberGenerator.generateOrderDateNumber(now));
        ticketOrder.setBuyTime(now);
        ticketOrder.setGmtCreate(now);
        ticketOrder.setGmtModified(now);

        log.debug("整合实体, ticketOrder={}", ticketOrder);
        int rows = mapper.insert(ticketOrder);
        if(rows != 1){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            String message = "添加购票订单失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.info("【结果1】:插入数据结果, rows = {}", rows);

        log.info("新增购票列表...");
        TicketList[] ticketLists = new TicketList[ticketOrderAddNewParam.getTotalNum()];
        for (int i = 0; i < ticketLists.length; i++) {
            TicketList ticketList = new TicketList();
            ticketList.setOrderId(ticketOrder.getId()).setNum(1)
                    .setPrice(ticketOrderAddNewParam.getPrice()).setPayStatus(PAY_PAID)
                    .setGmtCreate(now).setGmtModified(now);
            ticketLists[i] = ticketList;
        }
        log.debug("新增购票列表关系数据,ticketLists={}", ticketLists);
        rows = ticketListMapper.insertBatch(ticketLists);
        if(rows != ticketLists.length){
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", ticketLists.length, rows);
            String message = "添加购票列表失败，服务器忙，请稍后再试！";
            throw new ServiceException(ServiceCode.ERR_INSERT, message);
        }
        log.info("结果1:新增购票列表结果,rows={}", rows);
    }

    @Override
    public void deleteById(Long id) {
        log.info("【开始】:【根据ID删除—购票订单】");
        log.debug("传入参数, id={}", id);
        //检查购票订单ID检查购票订单是否存在数据，如果不存在，则抛出异常
        QueryWrapper<TicketOrder> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据购票订单id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据购票订单id检索数据量为0，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "删除购票订单失败，购票订单数据不存在！");
        }

        List<TicketListListItemVO> tickLists = null;
        tickLists = ticketListMapper.listByOrderIdAndPayStatus(id, PAY_PAID);
        if(tickLists != null && tickLists.size() > 0){
            log.info("结果3:根据购票订单id检索数据量为不为0，抛出异常...");
            String message = "该订单下存在【已付款】商品，无法删除";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }
        tickLists = ticketListMapper.listByOrderIdAndPayStatus(id, PAY_REFUND);
        if(tickLists != null && tickLists.size() > 0){
            log.info("结果4:根据购票订单id检索数据量为不为0，抛出异常...");
            String message = "该订单下存在【待退款】商品，无法删除";
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        log.info("删除购票订单...");
        int rows = mapper.deleteById(id);
        log.info("【结果1】:删除数据结果, rows = {}", rows);
        if(rows != 1){
            String message = "删除购票订单失败，服务器忙，请稍后再试！";
            log.info("结果1:数据返回行数不满足预估行数，预估={}, 实际={}, 抛出自定异常...", 1, rows);
            throw new ServiceException(ServiceCode.ERR_DELETE, message);
        }
        log.info("结果1:删除购票订单结果,rows={}", rows);

        log.info("删除购票列表数据...");
        rows = ticketListMapper.deleteByOrderId(id);
        log.info("结果1:删除购票列表结果,rows={}", rows);

    }

    @Override
    public void updateInfoById(Long id, TicketOrderUpdaeInfoParam cvsTicketOrderUpdaeInfoParam) {
        log.info("【开始】:【根据ID更新—购票订单】");
        log.debug("传入参数, id={}, bannerAddNewParam={}", id, cvsTicketOrderUpdaeInfoParam);

        //检查购票订单ID检查购票订单是否存在数据，如果不存在，则抛出异常
        QueryWrapper<TicketOrder> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("id", id);
        int countById = mapper.selectCount(queryWrapper2);
        log.info("规则：根据购票订单id检索数据库结果,countById={}", countById);
        if(countById == 0){
            log.info("结果2:根据购票订单id检索数据量为0，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "编辑购票订单失败，购票订单数据不存在！");
        }

        TicketOrder ticketOrder =new TicketOrder();
        BeanUtils.copyProperties(cvsTicketOrderUpdaeInfoParam, ticketOrder);
        ticketOrder.setId(id);
        log.debug("整合实体, banner={}", ticketOrder);
        int update = mapper.updateById(ticketOrder);
        log.info("【结果1】:更新数据结果, update = {}", update);
    }

    @Override
    public TicketOrderStandardVO getStandardById(Long id) {
        log.info("开始:【根据ID查询-购票订单】");
        log.debug("传入参数,id={}", id);
        TicketOrderStandardVO standardById=mapper.getStandardById(id);

        //根据购票订单ID检查购票订单是否存在数据，如果不存在，则抛出异常
        if(standardById==null){
            log.info("结果2:根据购票订单id查询详情，结果为null，抛出异常...");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "查询购票订单详情失败，购票订单数据不存在");
        }

        log.info("结果1:查询出数据,standardById");
        return standardById;
    }

    @Override
    public PageData<TicketOrderListItemVO> list(Integer pageNum) {
        Integer pageSize = 5;
        return list(pageNum, pageSize);
    }

    @Override
    public PageData<TicketOrderListItemVO> list(Integer pageNum, Integer pageSize) {
        log.info("开始:【查询-购票订单-分页】");
        log.debug("传入参数, pageNum={}, pageSize={}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<TicketOrderListItemVO> list = mapper.list();
        PageInfo<TicketOrderListItemVO> pageInfo = new PageInfo<>(list);
        PageData<TicketOrderListItemVO> pageData = PageInfoToPageDataConverter.converter(pageInfo);
        log.debug("结果1: 查询结果：pageData={}", pageData);
        return pageData;
    }

    @Override
    public PageData<TicketOrderListItemVO> listByUserId(Long userId, Integer pageNum) {
        Integer pageSize = 5;
        return listByUserId(userId, pageNum, pageSize);
    }

    @Override
    public PageData<TicketOrderListItemVO> listByUserId(Long userId, Integer pageNum, Integer pageSize) {
        log.info("开始:【查询-购票订单-分页】");
        log.debug("传入参数, pageNum={}, pageSize={}", pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize);
        List<TicketOrderListItemVO> list = mapper.listByUserId(userId);
        PageInfo<TicketOrderListItemVO> pageInfo = new PageInfo<>(list);
        PageData<TicketOrderListItemVO> pageData = PageInfoToPageDataConverter.converter(pageInfo);
        log.debug("结果1: 查询结果：pageData={}", pageData);
        return pageData;
    }
}
